home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_400 / 425_01 / tar / store.c < prev    next >
Text File  |  1980-07-23  |  7KB  |  287 lines

  1. /* store.c - storying files into (tape) archive
  2.  * This is the part of the Tar program (see file tar.c)
  3.  * Author: T.V.Shaporev
  4.  * Creation date 14 Dec 1990
  5.  */
  6. #include <stdio.h>
  7.  
  8. #include "sysup.h"
  9. #include "nodedef.h"
  10. #include "modern.h"
  11. #include "define.h"
  12.  
  13. char longname[] = "Tar: \'%s\' name too long%s";
  14.  
  15. #ifdef unix
  16. #    ifdef sun
  17. #        ifndef STDDIR
  18. #            define STDDIR
  19. #        endif
  20. #        include <dirent.h>
  21. #        define    DIRENT struct dirent
  22. #        define    namelen(d) strlen((d)->d_name)
  23. #    endif
  24. #    ifdef i386
  25. #        ifndef STDDIR
  26. #            define STDDIR
  27. #        endif
  28. #        include <dirent.h>
  29. #        define    DIRENT struct dirent
  30. #        define    namelen(d) strlen((d)->d_name)
  31. #    else
  32. #        ifdef M_XENIX
  33. #            ifndef STDDIR
  34. #                define STDDIR
  35. #            endif
  36. #            include <sys/ndir.h>
  37. #            define    DIRENT DIR
  38. #            define    namelen(d) ((d)->d_namlen)
  39. #        endif
  40. #    endif
  41. #endif
  42. #ifdef UNIX
  43. #    ifndef STDDIR
  44. #        include <sys/dir.h>
  45. #    endif
  46. #endif
  47.  
  48. #ifdef MSDOS
  49. #    include <string.h>
  50. #    ifdef __TURBOC__
  51. #        include <dir.h>
  52. #    else
  53. #        include <direct.h>
  54. #    endif
  55. #    include <io.h>
  56. #else
  57.     int  strlen();
  58.     char *strcpy(), *strcat(), *strncpy();
  59.     int  open(), read(), close();
  60. #    ifdef RMKDIR
  61.         int rmdir();
  62. #    endif
  63.     long lseek();
  64. #endif
  65.  
  66. #define dotname(n) ((n)[0]=='.' && ((n)[1]=='\0'||((n)[1]=='.'&&(n)[2]=='\0')))
  67.  
  68. void proctl  __ARGS__(( char *, long ));
  69. void procts  __ARGS__(( char *, short, char ));
  70. void prcsum  __ARGS__(( register struct header * ));
  71. void newhead __ARGS__(( char *, long ));
  72. char *deleft __ARGS__(( char * ));
  73.  
  74. void nullblock(h)
  75. struct header *h;
  76. {
  77.    register i; for (i=0; i<BLKSIZE/sizeof(int); i++) *((int *)h + i) = 0;
  78. }
  79.  
  80. void proctl(dest, l)
  81. char dest[]; long l;
  82. {
  83.    register int i;
  84.  
  85.    dest[i = 11] = ' ';
  86.    do dest[--i] = ((char)l & 7) | '0'; while (i>0 && (l>>=3)!=0);
  87.    while (i>0) dest[--i] = ' ';
  88. }
  89.  
  90. void procts(dest, s, suffix)
  91. char dest[]; short s; char suffix;
  92. {
  93.    register int i;
  94.  
  95.    dest[7] = 0;
  96.    dest[i = 6] = suffix;
  97.    do dest[--i] = (s & 7) | '0'; while (i>0 && (s>>=3)!=0);
  98.    while (i>0) dest[--i] = ' ';
  99. }
  100.  
  101. void prcsum(h)
  102. register struct header *h;
  103. {
  104.    register i;
  105.    /* for the sake of compatibility */
  106.    for (i=0; i<8; i++) (h->chksum)[i] = ' ';
  107.    procts(h->chksum, headsum(h), 0);
  108. }
  109.  
  110. void newhead(filename, filesize)
  111. char *filename;
  112. long filesize;
  113. {
  114.    nullblock(hblock = steptape());
  115.    procts(hblock->mode,  (short)st.st_mode & 07777, ' ');
  116.    procts(hblock->uid,   (short)st.st_uid, ' ');
  117.    procts(hblock->gid,   (short)st.st_gid, ' ');
  118.    proctl(hblock->size,  filesize);
  119.    proctl(hblock->mtime, st.st_mtime);
  120.    (void)strncpy(hblock->name, filename, MAXTNAME);
  121. }
  122.  
  123. char *deleft(p)
  124. register char *p;
  125. {
  126. #ifdef MSDOS
  127.    if (deldrv && p[1] == ':' &&
  128.                 (p[0]>='A' && p[0]<='Z' || p[0]>='a' && p[0]<='z'))
  129.       p += 2;
  130. #endif
  131.    if (dslash && *p == '/') ++p;
  132.    return p;
  133. }
  134.  
  135. void store(fname)
  136. char *fname;
  137. {
  138.    register i; register j;
  139.    register unsigned m;
  140.    static level = 0;
  141. #ifdef UNIX
  142.    register char *p;
  143. #  ifdef STDDIR
  144.       register DIR *d0; register DIRENT *dp;
  145. #  else
  146.       register char *q; struct direct d_buf; int infile;
  147. #  endif
  148. #endif
  149.  
  150. #ifdef MSDOS
  151.    register k;
  152.    struct ffblk ff;
  153. #endif
  154.  
  155.    if (cbreak) done(0); ++level;
  156.  
  157.    if (strlen(fname) > MAXTNAME) {
  158.       (void)fprintf(myout, longname, fname, "\n");
  159.       goto end;
  160.    }
  161. #ifdef MSDOS
  162.    i = FALSE;
  163.    for (j=strlen(fname); j>0 && fname[j-1]!='/' && fname[j-1]!=':'; j--) {
  164.       if (fname[j-1]=='?' || fname[j-1]=='*') i = TRUE;
  165.    }
  166.  
  167.    if (i) {
  168.       k = findfirst(fname, &ff, filemask);
  169.       while (k==0 && dotname(ff.ff_name)) k = findnext(&ff);
  170.       if (k) {
  171.          if (level < 2) (void)fprintf(myout,"Tar: can\'t find \'%s\'\n",fname);
  172.          goto end;
  173.       }
  174.       do {
  175.          takename(fname+j, ff.ff_name);
  176.          store(fname);
  177.       } while (findnext(&ff) == 0);
  178.       goto end;
  179.    }
  180. #endif
  181.    if (stat(fname, &st) < 0) {
  182.       (void)fprintf(myout, "Tar: can\'t handle \'%s\'\n", fname);
  183.       goto end;
  184.    }
  185.    if ((m = st.st_mode & S_IFMT) == S_IFDIR) {
  186.       if (nonest && level > 1) goto end;
  187.  
  188. #ifdef UNIX
  189.       if (p_flag) {/* save directory & permissions */
  190.          newhead((p = deleft(fname)), 0L);
  191.          if ((j = strlen(p)) < MAXTNAME-1) {
  192.             hblock->name[j+1] = '\0';
  193.          } else {
  194.             j = MAXTNAME-1;
  195.          }
  196.          hblock->name[j] = '/';
  197.          prcsum(hblock);
  198.       }
  199. #  ifdef STDDIR
  200.       if ((d0 = opendir(fname)) == NULL) {
  201.          (void)fprintf(myout, "Tar: can\'t open directory \'%s\'\n", fname);
  202.          goto end;
  203.       }
  204.       fname[i = strlen(fname)] = '/'; *(p = ++i + fname) = 0;
  205.  
  206.       for (dp=readdir(d0); dp; dp=readdir(d0)) {
  207.      j = namelen(dp);
  208.          if (j==0 ||
  209.             (j==1 && (dp->d_name)[0]=='.') ||
  210.             (j==2 && (dp->d_name)[0]=='.' && (dp->d_name[1])=='.'))
  211.             continue;
  212.          for (i=0; i<j; i++) p[i] = (dp->d_name)[i];
  213.          p[j] = 0;
  214.          store(fname);
  215.       }
  216.       closedir(d0);
  217. #  else
  218.       if ((infile = open(fname, O_RDONLY)) < 0) {
  219.          (void)fprintf(myout, "Tar: can\'t open file \'%s\'\n", fname);
  220.          goto end;
  221.       }
  222.       fname[i = strlen(fname)] = '/'; *(p = ++i + fname) = 0;
  223.  
  224.       i = 0;
  225.       while (read(infile, (char*)&d_buf, sizeof(d_buf)) > 0 && !cbreak) {
  226.          if (d_buf.d_ino!=0 && !dotname(d_buf.d_name)) {
  227.             q = p;
  228.             for (j=0; j<DIRSIZ; j++) *q++ = d_buf.d_name[j];
  229.             *q = '\0';
  230.             (void)close(infile); /* need this file handler */
  231.             store(fname);
  232.             *p = '\0';
  233.             infile = open(fname, O_RDONLY);
  234.             (void)lseek(infile, (long)(sizeof(d_buf) * (i+1)), 0);
  235.          }
  236.          ++i;
  237.       }
  238. #  endif
  239.       if (y_flag) {
  240. #        ifdef RMKDIR
  241.             if (rmdir(fname) != 0) {
  242.                (void)fprintf(myout, "Tar: can\'t remove \'%s\'\n", fname);
  243.             }
  244. #        else
  245.             if (bincall("rmdir", fname) == -1) {
  246.                (void)fprintf(myout, "Tar: fault run rmdir!\n");
  247.             }
  248. #        endif
  249.       }
  250. #endif
  251. #ifdef MSDOS
  252.       j = strlen(fname);
  253.       strcpy(fname+j, "/*.*");
  254.  
  255.       store(fname);
  256.  
  257.       if (y_flag) {
  258.          fname[j] = 0;
  259.          if (rmdir(fname) != 0) {
  260.             (void)fprintf(myout, "Tar: can\'t remove \'%s\'\n", fname);
  261.          }
  262.       }
  263. #endif
  264.    } else if (m == S_IFREG) {
  265.       savefile(fname);
  266.    } else {
  267. #ifdef UNIX
  268.       p = deleft(fname);
  269.       if (w_flag && !okwork('a', ' ', &st, fname)) goto end;
  270.       if (v_flag) (void)fprintf(myout, "a %s\n", p);
  271.       if (m == S_IFCHR || m == S_IFBLK || m == S_IFIFO) {
  272.          newhead(p, 0L);
  273.          if (m == S_IFIFO) {
  274.             hblock->filetype = TF_QUE;
  275.          } else {
  276.             hblock->filetype = m == S_IFBLK ? TF_BLK : TF_CHR;
  277.             procts(hblock->x.new.devmajor, major(st.st_rdev), ' ');
  278.             procts(hblock->x.new.devminor, minor(st.st_rdev), ' ');
  279.          }
  280.          prcsum(hblock);
  281.       } else
  282. #endif
  283.          (void)fprintf(myout, "Tar: \'%s\' not a file\n", fname);
  284.    }
  285. end: --level;
  286. }
  287.